package core;

import java.util.Random;

import javax.swing.JOptionPane;

public class Environment {
	public enum Type {
		STATIC, DYNAMIC1, DYNAMIC2, DYNAMIC3
	}

	public AbstractAgent agent;
	public Action.Type currAction;
	public Type type;
	public Floor floor;
	public int kSteps;
	public int stepsToChange;

	public Environment(AbstractAgent agent, Environment.Type dynType, int kSteps) {
		this.floor = new Floor();
		if(this.floor.rooms[agent.x].squares[agent.y].type != Square.Type.clean) {
			do {
				Random random = new Random();
				agent.y = Math.abs(random.nextInt()) % 8;
			} while(this.floor.rooms[agent.x].squares[agent.y].type == Square.Type.clean);
		}
		this.agent = agent;
		this.type = dynType;
		this.kSteps = kSteps;
		this.stepsToChange = kSteps;
	}

	public Perception getPerceptions() {
		/* create a perception with a floor of unknown state */
		Perception perception = new Perception(this.floor);
		/* then add informations according to the agent visibility */

		/* add informations about all the squares */
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 8; j++)
				perception.floor.set(i, j, floor.get(i, j));
		return perception;
	}

	public void update() {
		agent.perceives(getPerceptions());
		agent.update();
		getAction(agent.action());
		System.out.println("Action received: " + currAction);
		
		if (type == Environment.Type.DYNAMIC1) {
			if (this.stepsToChange == 0) {
				this.floor.dynamic1();
				this.stepsToChange = this.kSteps;
				this.agent.maxSteps = this.stepsToChange;
			} else {
				this.stepsToChange--;
				this.agent.maxSteps = this.stepsToChange;
			}
		}else if (type == Environment.Type.DYNAMIC2) {
			if (this.stepsToChange == 0) {
				this.floor.dynamic2();
				this.stepsToChange = this.kSteps;
				this.agent.maxSteps = this.stepsToChange;
			} else {
				this.stepsToChange--;
				this.agent.maxSteps = this.stepsToChange;
			}
		} else if (type == Environment.Type.DYNAMIC3) {
			if (this.stepsToChange == 0) {
				this.floor.dynamic3();
				this.stepsToChange = this.kSteps;
				this.agent.maxSteps = this.stepsToChange;
			} else {
				this.stepsToChange--;
				this.agent.maxSteps = this.stepsToChange;
			}
		}

		if (currAction == Action.Type.DO) {
			JOptionPane.showMessageDialog(null, floor.get(agent.x, agent.y) + " reached!");
			System.out.println("MY CELL BEFORE: " + agent.x + "," + agent.y + ": " + floor.get(agent.x, agent.y));
		}
		if (currAction == Action.Type.NORTH && agent.x - 1 >= 0 && floor.isDoor(agent.x - 1, agent.y))
			agent.x--;
		if (currAction == Action.Type.SOUTH && agent.x + 1 < 4 && floor.isDoor(agent.x, agent.y))
			agent.x++;
		if (currAction == Action.Type.EAST && agent.y + 1 < 8)
			agent.y++;
		if (currAction == Action.Type.WEST && agent.y - 1 >= 0)
			agent.y--;
	}

	public void getAction(Action.Type action) {
		currAction = action;
	}

	public int performanceMeasure() {
		return this.agent.timeToRenata/(this.agent.goals.size() + 1);
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++)
				if (i % 2 == 0) {
					if (agent.x == i / 2 && agent.y == j)
						sb.append("[[=]] ");
					else if (floor.get(i / 2, j) == Square.Type.flowers)
						sb.append("FFFFF ");
					else if (floor.get(i / 2, j) == Square.Type.meal)
						sb.append("MMMMM ");
					else if (floor.get(i / 2, j) == Square.Type.smoking)
						sb.append("SSSSS ");
					else if (floor.get(i / 2, j) == Square.Type.table)
						sb.append("TTTTT ");
					else
						sb.append("----- ");
				} else {
					int tmp = i / 2 - 1 / 2;
					if (tmp == 3 && floor.isDoor(tmp, j))
						sb.append("OOOOO ");
					else if (floor.isDoor(tmp, j))
						sb.append("@@@@@ ");
					else
						sb.append("##### ");
				}
			sb.append("\n");
		}
		return sb.toString();
	}

	public void show() {
		System.out.println(this);
	}
}